package com.yd.mvc.baseController.util;

import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;

/**
 * Created by zq on 2015/12/17.
 * 自定义参数和返回结果处理器
 */
public class JsonArgumentResolver extends RequestResponseBodyMethodProcessor {
    public JsonArgumentResolver(List<HttpMessageConverter<?>> messageConverters,
                                              ContentNegotiationManager contentNegotiationManager) {
        super(messageConverters, contentNegotiationManager);
    }
    public JsonArgumentResolver(List<HttpMessageConverter<?>> messageConverters) {
        super(messageConverters);
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(RequestBody.class);
    }

    /**
     * 将参数放入request中，方便记录参数
     * @param webRequest
     * @param methodParam
     * @param paramType
     * @param <T>
     * @return
     * @throws IOException
     * @throws HttpMediaTypeNotSupportedException
     */
    @Override
    protected <T> Object readWithMessageConverters(NativeWebRequest webRequest, MethodParameter methodParam, Type paramType) throws IOException, HttpMediaTypeNotSupportedException {
        final HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
        HttpInputMessage inputMessage = new ServletServerHttpRequest(servletRequest);
        T res= (T) super.readWithMessageConverters(inputMessage, methodParam, paramType);
        webRequest.setAttribute("requestBody",res,RequestAttributes.SCOPE_REQUEST);
        return res;
    }

    /**
     * 统一处理返回结果，将结果封装为JsonResult类型
     * @param returnValue
     * @param returnType
     * @param mavContainer
     * @param webRequest
     * @throws IOException
     * @throws HttpMediaTypeNotAcceptableException
     */
    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType,
                                  ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
            throws IOException, HttpMediaTypeNotAcceptableException {
        mavContainer.setRequestHandled(true);
        if(returnValue instanceof JsonResult){
            writeWithMessageConverters(returnValue, returnType, webRequest);
        }else{
            writeWithMessageConverters(new JsonResult(1,returnValue,""), returnType, webRequest);
        }

    }
}
